package ListBook;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Observable;
import java.util.UUID;

import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;

/**
 * ****************************************
 * FILENAME: Note.java
 * ****************************************
 * Container fuer die Daten einer Notiz.
 * 
 * @author Kove / HOEFI
 * @since 28.01.2015
 * @version 1.0
 */
public class Note extends Observable implements Serializable, ListChangeListener<Object> {

  private static final long serialVersionUID = 5599561789853563966L;

  /**
   * Notiztitel: Wird nur im Konstruktor gesetzt.
   */
  private String noteTitle = "";
  /**
   * Erstelldatum und Zeit: Read-only!
   */
  private LocalDateTime createDateTime = LocalDateTime.now();
  /**
   * Notiztext
   */
  private String noteText = "";
  /**
   * Liste mit Weblinks: transient, weil ObservableList nicht direkt serialisierbar.
   */
  private transient ObservableList<String> urlList = Utilities.createNewObservableList(this);
  /**
   * Liste mit Pfaden zu Bildern: transient, weil ObservableList nicht direkt serialisierbar.
   */
  private transient ObservableList<String> imageList = Utilities.createNewObservableList(this);
  /**
   * Dateiname bestehend aus einer generierten GUID: Read-only!
   */
  private String fileGUID = UUID.randomUUID().toString() + ".dat";

  /**
   * Konstruktor
   * 
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @param title
   *          Titel der Notiz.
   */
  public Note(String title) {
    noteTitle = title;
  }

  /**
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @return Gibt Klassenmember "title" zurueck.
   */
  public String getNoteTitle() {
    return noteTitle;
  }

  /**
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @return Gibt Klassenmember "createDateTime" zurueck.
   */
  public String getCreateDateTime() {
    DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm");
    return createDateTime.format(dateFormat);
  }

  /**
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @return Gibt Klassenmember "noteText" zurueck.
   */
  public String getNoteText() {
    return noteText;
  }

  /**
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @param noteText
   *          Setzt Klassenmember "noteText".
   */
  public void setNoteText(String noteText) {
    this.noteText = noteText;
    setChanged();
    notifyObservers(this);
  }

  /**
   * @author Kove / HOEFI
   * @since 28.01.2015
   * @return Gibt Klassenmember "urlList" zurueck.
   */
  public ObservableList<String> getUrlList() {
    return urlList;
  }

  /**
   * @author Kove / HOEFI
   * @since 15.02.2015
   * @return Gibt Klassenmember "imageList" zurueck.
   */
  public ObservableList<String> getImageList() {
    return imageList;
  }

  /**
   * @author Kove / HOEFI
   * @since 15.02.2015
   * @return Gibt Klassenmember "fileGUID" zurueck.
   */
  public String getFileGUID() {
    return fileGUID;
  }

  /**
   * Schreibt alle Klassenmember des Objekts serialisiert in den uebergebenen ObjectOutputStream.
   * 
   * @author Kove / HOEFI
   * @since 24.02.2015
   * @param stream
   * @throws IOException
   */
  private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.writeObject(noteTitle);
    stream.writeObject(createDateTime);
    stream.writeObject(noteText);
    stream.writeObject(fileGUID);
    // URL und Bilder als Array speichern.
    stream.writeObject(imageList.toArray());
    stream.writeObject(urlList.toArray());
  }

  /**
   * Deserialisiert aus dem uebergebenen ObjectInputStream alle Klassemmember des Objekts.
   * 
   * @author Kove / HOEFI
   * @since 24.02.2015
   * @param stream
   * @throws IOException
   * @throws ClassNotFoundException
   */
  private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
    noteTitle = (String) stream.readObject();
    createDateTime = (LocalDateTime) stream.readObject();
    noteText = (String) stream.readObject();
    fileGUID = (String) stream.readObject();
    // Bilder-Liste als Object-Array einlesen.
    imageList = Utilities.createNewObservableList(this);
    for (Object image : (Object[]) stream.readObject())
      imageList.add((String) image);
    // URL-Liste als Object-Array einlesen.
    urlList = Utilities.createNewObservableList(this);
    for (Object url : (Object[]) stream.readObject())
      urlList.add((String) url);
  }

  /*
   * (non-Javadoc)
   * 
   * @see javafx.collections.ListChangeListener#onChanged(javafx.collections.ListChangeListener.Change)
   */
  @Override
  public void onChanged(Change<? extends Object> c) {
    setChanged();
    notifyObservers(this);
  }
}
